#include "viewer.h"

#include <string>
#include <iostream>

#ifdef _MAC_OS_
#include <GLUT/glut.h>
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#else
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#endif

using namespace std;

Viewer::Viewer():
  _halfSize(0.5),
  _growing(true),
  _out(true){  
}


Viewer::~Viewer(){

}


////////////////////////////////////////////////////////////////////////////////
// GL stuff

// initialize OpenGL context
void
Viewer::init(int w, int h){
  vec2f dim(0.3, 0.3);
  vec2f pos(-1.0,-1.0);
  vec3f color(0.f, 1.f, 0.f);
  _square._dim = dim;
  _square._pos = pos;
  _square._color = color;
  // background color
  glClearColor (0.0, 0.0, 0.0, 1.0);
  // viewport
  glViewport (0, 0, w, h);
}

void
Viewer::reshape(int w, int h){
  glViewport (0, 0, w, h);
}


/*!
   callback to draw graphic primitives
   you may edit it if you want to change de drawing procedure (add new objects
   for example).
 */
void
Viewer::display() const{
  // clear current buffer
  glClear (GL_COLOR_BUFFER_BIT);

  // define projetion matrix
  glMatrixMode (GL_PROJECTION);
  glLoadIdentity (); 
  glOrtho (-1.1, 1.1, -1.1, 1.1, -10, 10);

  // define model view matrix
  glMatrixMode (GL_MODELVIEW);
  glLoadIdentity ();

  /////////////////////////////////////
  // Draw the primitives.
  
  _square.draw();
  
  // End of drawing
  /////////////////////////////////////

  glFlush();
}

/*!
   draw a simple red square. 
   This function illustrate how to render simple 2D geometry in OpenGL
*/
void
Viewer::drawRedSquare () const
{
  // Specify the color in RGB in [0;1] range.
  //glColor3f(1.f,0.f,0.f);
  glColor3f(_square._color._x, _square._color._y, _square._color._z);

  // Begin OpenGL call : display two triangles to have a square
  // This square is positionned in [-0.5, -0.5] and have a width
  // and a height equals to 1.
  glBegin (GL_TRIANGLES);
  glVertex2f (_square._pos._x, _square._pos._y);
  glVertex2f (_square._pos._x, _square._pos._y + _square._dim._y);
  glVertex2f (_square._pos._x + _square._dim._x, _square._pos._y);
  
  glVertex2f (_square._pos._x + _square._dim._x, _square._pos._y + _square._dim._y);
  glVertex2f (_square._pos._x, _square._pos._y + _square._dim._y);
  glVertex2f (_square._pos._x + _square._dim._x, _square._pos._y);

  glEnd ();
}

void 
Viewer::updateScene () {
  /*
  if (_growing){ // grow square
     _square._dim._x += 0.0001;
     _square._dim._y += 0.0001;
     _growing = _square._dim._x < 0.7;
    } else {
     _square._dim._x -= 0.0001;
     _square._dim._y -= 0.0001;
     _growing = _square._dim._x < 0.4;
   }
  */
   /*
   vec2f newPos(_square._pos._x + 0.01, _square._pos._y + 0.01);
   _square.setPosition(newPos);
   */
  vec2f newPos(_square._pos._x + _square._speed._x, _square._pos._y + _square._speed._y);
   _square.setPosition(newPos);

   display();
}


////////////////////////////////////////////////////////////////////////////////
// Events

/*!
   callback to manage mouse : called when user press or release mouse button
   You can change in this function the way the user 
   interact with the system.
 */
void  
Viewer::mousePressed(int button, int state, int x, int y){
   std::string buttonName;

   switch(button){
   case GLUT_LEFT_BUTTON:
      buttonName = string("left");
      break;
   case GLUT_MIDDLE_BUTTON:
      buttonName = string("middle");
      break;
   case GLUT_RIGHT_BUTTON:
      buttonName = string("right");
      break;
   default:
      buttonName = string("invalid");
   }

   cout << "User " 
        << (state == GLUT_DOWN ? "press " : "release ")
        << buttonName.c_str()
        << " button in "
        << x 
        << ", "
        << y
        << endl;

   //Compute speed
   float speedx = 0;
   float speedy = 0;
   float alphaSpeed = 0.0001;

   float realPosx = (x + 300) / 300.0;
   float realPosy = (y + 300) / 300.0;
   
   speedx = realPosx - (_square._pos._x + _square._dim._x/2);
   speedy = realPosy - (_square._pos._y - _square._dim._y/2); 

   cout << "realPosx = "
        << realPosx
        << " & speedx = "
        << speedx
        << endl;

   speedx *= alphaSpeed;
   speedy *= alphaSpeed;
   vec2f speed(speedx, speedy);
   _square.setSpeed(speed);

   // request display refresh
   glutPostRedisplay(); 
}


 
 
/*!
   callback to manage mouse : called when user move mouse with button pressed
   You can change in this function the way the user 
   interact with the system.
 */
void
Viewer::mouseMoved(int x, int y){
     cout << "Mouse moved in "
        << x 
        << ", "
        << y
        << endl;

   // request display refresh
   glutPostRedisplay(); 
}


/*!
   callback to manage keyboard interactions
   You can change in this function the way the user 
   interact with the system.
 */
void
Viewer::keyPressed(unsigned char key, int x, int y){

}
